package com.ac.scum.log.web.model.player.service;

import com.ac.common.core.exception.BaseException;
import com.ac.common.core.exception.config.ExceptionType;
import com.ac.scum.log.web.model.player.mapper.PlayerCustomizePackageMapper;
import com.ac.scum.log.web.utils.user.CurrentUserUtil;
import com.ac.scum.player.bean.PlayerBalance;
import com.ac.scum.player.bean.PlayerConsumeTrade;
import com.ac.scum.player.bean.PlayerCustomizePackage;
import com.ac.scum.player.bean.ServerCustomizePackage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.micrometer.common.util.StringUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class PlayerCustomizePackageService extends ServiceImpl<PlayerCustomizePackageMapper, PlayerCustomizePackage> {
    private final PlayerService playerService;
    private final PlayerBalanceService playerBalanceService;
    private final PlayerConsumeTradeService playerConsumeTradeService;
    private final ServerCustomizePackageService serverCustomizePackageService;

    public Long findPackageCount(Long serverId, Long packageId) {
        return this.getBaseMapper().selectCount(Wrappers.<PlayerCustomizePackage>lambdaQuery()
                .gt(PlayerCustomizePackage::getExpirationTime, LocalDateTime.now())
                .gt(PlayerCustomizePackage::getSurplus, 0)
                .eq(PlayerCustomizePackage::getServerId, serverId)
                .eq(PlayerCustomizePackage::getPackageId, packageId));
    }

    @Transactional
    public Boolean pay(PlayerConsumeTrade playerConsumeTrade) throws BaseException {
        if (playerConsumeTrade == null) {
            throw new BaseException(ExceptionType.Parameter_Error.of("订单异常"));
        }
        playerConsumeTrade.setServerId(CurrentUserUtil.getCurrentServerId());

        PlayerBalance playerBalance = playerBalanceService.findPlayerBalance(playerConsumeTrade.getServerId(), playerConsumeTrade.getPlayerId());

        if (playerBalance.getBalance() < playerConsumeTrade.getAmount()) {
            throw new BaseException(ExceptionType.Parameter_Error.of("该玩家余额不足"));
        }
        // 玩家套餐
        if (playerConsumeTrade.getType().equals("1")) {
            if (playerConsumeTrade.getCustomizePackageId() == null) {
                throw new BaseException(ExceptionType.Parameter_Error.of("套餐CustomizePackageId 不可为空"));
            }
            if (playerConsumeTrade.getPlayerId() == null) {
                throw new BaseException(ExceptionType.Parameter_Error.of("玩家Id 不可为空"));
            }
            ServerCustomizePackage serverCustomizePackage = serverCustomizePackageService.getById(playerConsumeTrade.getCustomizePackageId());
            if (serverCustomizePackage == null) {
                throw new BaseException(ExceptionType.Parameter_Error.of("套餐不存在"));
            }

            PlayerCustomizePackage playerCustomizePackage = this.getOne(Wrappers.<PlayerCustomizePackage>lambdaQuery()
                    .eq(PlayerCustomizePackage::getPlayerId, playerConsumeTrade.getPlayerId())
                    .eq(PlayerCustomizePackage::getServerId, playerConsumeTrade.getServerId())
                    .eq(PlayerCustomizePackage::getPackageId, playerConsumeTrade.getCustomizePackageId()));
            if (playerCustomizePackage == null || playerCustomizePackage.getExpirationTime().isBefore(LocalDateTime.now()) || playerCustomizePackage.getSurplus() == 0) {
                if (playerCustomizePackage != null) {
                    this.getBaseMapper().deleteById(playerCustomizePackage.getId());
                } else {
                    playerCustomizePackage = new PlayerCustomizePackage();
                    playerCustomizePackage.setExpirationTime(LocalDateTime.now());
                    playerCustomizePackage.setPackageId(playerConsumeTrade.getCustomizePackageId());
                    playerCustomizePackage.setPlayerId(playerConsumeTrade.getPlayerId());
                    playerCustomizePackage.setPlayerSteamId(playerConsumeTrade.getPlayerSteamId());
                    playerCustomizePackage.setServerId(playerConsumeTrade.getServerId());
                    playerCustomizePackage.setSurplus(0L);
                }

            }
            playerCustomizePackage.setSurplus(playerCustomizePackage.getSurplus() + serverCustomizePackage.getNum());
            playerCustomizePackage.setExpirationTime(playerCustomizePackage.getExpirationTime().plusHours(serverCustomizePackage.getHour()));
            if (playerCustomizePackage.getId() == null) {
                this.save(playerCustomizePackage);
            } else {
                this.updateById(playerCustomizePackage);
            }
        }

        playerConsumeTradeService.save(playerConsumeTrade);

        playerBalance.setBalance(playerBalance.getBalance() - playerConsumeTrade.getAmount());
        playerBalance.setLastConsumeTradeId(playerConsumeTrade.getId());
        playerBalance.setLastConsumeTime(LocalDateTime.now());
        playerBalanceService.updateById(playerBalance);

        return Boolean.TRUE;
    }

    public Page<PlayerCustomizePackage> page(Page<?> page, Long serverId, String steamId, String adminName, String packageName, Boolean isActive) throws BaseException {
        StringBuilder sql = new StringBuilder(" 1=1");
        if (StringUtils.isNotBlank(steamId)) {
            sql.append(" and player_steam_id = ").append(steamId).append(" ");
        }
        if (StringUtils.isNotBlank(packageName)) {
            LambdaQueryWrapper<ServerCustomizePackage> where = Wrappers.lambdaQuery(ServerCustomizePackage.class).like(ServerCustomizePackage::getName, packageName).eq(ServerCustomizePackage::getServerId, CurrentUserUtil.getCurrentServerId());
            List<ServerCustomizePackage> serverCustomizePackages = serverCustomizePackageService.getBaseMapper().selectList(where);
            if (!serverCustomizePackages.isEmpty()) {
                String joinSql = serverCustomizePackages.stream().map(ServerCustomizePackage::getId).map(String::valueOf).collect(Collectors.joining(","));
                sql.append(" and package_id in (").append(joinSql).append(") ");
            } else {
                return new Page<>();
            }
        }
        if (StringUtils.isNotBlank(adminName)) {
            sql.append(" and admin_name like '%").append(adminName).append("%' ");
        }

        if (isActive != null) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String nowStr = LocalDateTime.now().format(formatter);
            if (isActive) {
                sql.append(" and expiration_time > '").append(nowStr).append("' ");
                sql.append(" and surplus > 0 ");
            } else {
                sql.append(" and expiration_time < '").append(nowStr).append("' ");
                sql.append(" and surplus = 0 ");
            }
        }
        Page<PlayerCustomizePackage> playerCustomizePackagePageByWhere = this.getBaseMapper().findPlayerCustomizePackagePageByWhere(page, serverId, sql.toString());

        for (PlayerCustomizePackage record : playerCustomizePackagePageByWhere.getRecords()) {
            record.setPlayer(playerService.findPlayerById(record.getServerId(), record.getPlayerId()));
        }
        return playerCustomizePackagePageByWhere;
    }
}
